/*
* @validateUtils.js
* @description 表单验证脚本
* @author chenzhihui
* @update (chenzhihui 2019/3/30)
*/
import {Message} from 'element-ui'
import regexDict from './regexDict'
/*************************************************************************校验策略对象****************************************************************************/
/**
 * 这里我们定义校验的算法，使用到正则时名称应该
 * 尽量与所使用到的regexDict的正则相对应
 * */
let strategies = {
    /***********************对象是否为空**************************/
    isEmpty: function (value) {
        if (!value) {
            return {res: false, msg: '传入参数为空'};
        }
        if (Object.prototype.toString.call(value) === "[object Array]" && JSON.stringify(value) === '[]') {
            return {res: false, msg: '传入参数为空'};
        }
        if (Object.prototype.toString.call(value) === "[object Object]" && JSON.stringify(value) === '{}') {
            return {res: false, msg: '传入参数为空'};
        }
        //校验对象内的第一层字段是否为空
        for (var key in value) {
            if (value[key].length === 0) {
                return {res: false, msg: key + '字段为空'};
            }
        }
        return {res: true, msg: ''};
    },
    /***********************是否为整数**************************/
    isInteger: function (value) {
        let regex = new RegExp(regexDict.isInteger)
        if (regex.test(value)) {
            return {res: true, msg: ''};
        } else {
            return {res: false, msg: '必须是整数'};
        }
    },
    /***********************是否为正整数**************************/
    isIntegerPos: function (value) {
        let regex = new RegExp(regexDict.isIntegerPos)
        if (regex.test(value)) {
            return {res: true, msg: ''};
        } else {
            return {res: false, msg: '必须是正整数'};
        }
    },
    /***********************是否为纯中文**************************/
    isChinesTxt: function (value,) {
        var reg = new RegExp(regexDict.isChinesTxt, "g");
        if (reg.test(value)) {
            return {res: true, msg: ''};
        } else {
            return {res: false, msg: '必须是纯中文'};
        }
    },
    /***********************是否为八位固话**************************/
    isENum: function (value) {
        var reg = new RegExp(regexDict.isENum);
        if (reg.test(value)) {
            return {res: true, msg: ''};
        } else {
            return {res: false, msg: '必须是八位且合法的号码'};
        }
    },

    /***********************是否为十一位电话**************************/
    isElNum: function (value) {
        var reg = new RegExp(regexDict.isElNum);
        if (reg.test(value)) {
            return {res: true, msg: ''};
        } else {
            return {res: false, msg: '必须是十一位且合法的号码'};
        }
    },
    /***********************是否为十一位或者八位电话**************************/
    isElNumOrENum: function (value) {
        var regElNum = new RegExp(regexDict.isElNum);
        var regENum = new RegExp(regexDict.isENum);
        if (regElNum.test(value) || regENum.test(value)) {
            return {res: true, msg: ''};
        } else {
            return {res: false, msg: '必须是十一位号码或者八位号码且合法的号码'};
        }
    },
    /***********************校验身份证格式**************************/
    isLegalityIdCard: function (value) {
        // 加权因子
        var weight_factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        // 校验码
        var check_code = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
        var code = value + "";
        var last = value[17];//最后一位
        var seventeen = code.substring(0, 17);
        // ISO 7064:1983.MOD 11-2
        // 判断最后一位校验码是否正确
        var arr = seventeen.split("");
        var len = arr.length;
        var num = 0;
        for (var i = 0; i < len; i++) {
            num = num + arr[i] * weight_factor[i];
        }
        // 获取余数
        var resisue = num % 11;
        var last_no = check_code[resisue];
        // 格式的正则
        // 正则思路
        /*
        第一位不可能是0
        第二位到第六位可以是0-9
        第七位到第十位是年份，所以七八位为19或者20
        十一位和十二位是月份，这两位是01-12之间的数值
        十三位和十四位是日期，是从01-31之间的数值
        十五，十六，十七都是数字0-9
        十八位可能是数字0-9，也可能是X
        */
        var idcard_patter = new RegExp(regexDict.isLegalityIdCard);
        // 判断格式是否正确
        var format = idcard_patter.test(value);
        // 返回验证结果，校验码和格式同时正确才算是合法的身份证号码
        if (!((last === last_no) && format)) {
            return {res: false, msg: '身份证不合法！'};
        } else {
            return {res: true, msg: ''};
        }
    },
    /***********************是否为email格式**************************/
    isEmail: function (value) {
        var reg = new RegExp(regexDict.isEmail);
        if (!reg.test(value)) {
            return {res: false, msg: 'email格式不合法！'};
            ;
        } else {
            return {res: true, msg: ''};
            ;
        }
    },
    /***********************经纬度是否合法**************************/
    isPosition: function (value) {
        //兼容传入格式 'lat,lon'与[lat,lon]
        let lat = '';
        let lon = '';
        if (Object.prototype.toString.call(value) === "[object String]") {
            let str = value.split(",");
            lon = str[0];
            lat = str[1];
        }
        if (Object.prototype.toString.call(value) === "[object Array]") {
            lon = value[0];
            lat = value[1];
        }
        var regLat = new RegExp(regexDict.isPositionLat);
        var regLon = new RegExp(regexDict.isPositionLon);
        if (!regLat.test(lat) || !regLon.test(lon)) {
            return {res: false, msg: '经纬度不合法！'};
        } else {
            return {res: true, msg: ''};
        }
    },
    /***********************是否是浮点数**************************/
    isFloat: function (value) {
        var reg = new RegExp(regexDict.isFloat);
        if (!reg.test(value)) {
            return {res: false, msg: '必须是两位浮点小数！'};
            ;
        } else {
            return {res: true, msg: ''};
        }
    },
    /***********************是否是正浮点数**************************/
    isFloatPos: function (value) {
        var reg = new RegExp(regexDict.isFloatPos);
        if (!reg.test(value)) {
            return {res: false, msg: '必须是正的两位浮点小数！'};
            ;
        } else {
            return {res: true, msg: ''};
        }
    },


    /***********************是否仅包含汉字、数字(未完成)**************************/
    isCHTxtOrNum: function (value) {
        var reg = new RegExp(regexDict.isCHTxtOrNum);
        if (!reg.test(value)) {
            return {res: false, msg: '只允许包含汉字和数字'};
            ;
        } else {
            return {res: true, msg: ''};
        }
    },
    /***********************是否仅包含汉字、数字和标点(未完成)**************************/
    isCHTxtOrNumOrPun: function (value) {
        var reg = new RegExp(regexDict.isCHTxtOrNumOrPun);
        if (!reg.test(value)) {
            return {res: false, msg: '只允许包含汉字、数字和标点！'};
            ;
        } else {
            return {res: true, msg: ''};
        }
    },
};
/*************************************************************************校验Validator对象****************************************************************************/
let Validator = {
    /**
     *
     * @param formData 需要校验的数据
     * @param checkInfo 校验信息,传入结构如下:
     * formkey:是你传入校验数据的键，比如你校验的表单key是name，那么formkey就应该是name
     * rules:是你校验字段所使用的校验规则方法，详情查看本脚本中的 strategies 对象，比如你要校验他非空且最小长度为10，则是rules:['isNonEmpty']
     * checkInfo = {
     *     formkey:{rules:[]}
     * }
     *  @param callBackFun 回调方法，可选，返回校验结果，供用户自己操作
     */
    checkFormData(formData, checkInfo,callBackFun) {
        let checkReuslt = {res: true, msg: '校验通过'};
        if (!formData || !checkInfo) {
            console.error('方法参数传入有误，请检查')
            return
        }
        //遍历表单数据
        for (var key in formData) {
            //遍历所需要使用的校验规则
            try {
                checkInfo[key].rules.forEach((val) => {
                    //将表单值和表单中文解释传入校验方法
                    let checkRes = strategies[val](formData[key]);
                    //如果传入了回调方法，就把校验结果传递出去
                    if(Object.prototype.toString.call(value) === "[object Function]"){
                        callBackFun(checkRes)
                    }
                    if (checkRes.res) {}
                    //有一个校验没通过就抛出，停止遍历
                    else {
                        checkReuslt = {res: false, msg: key + '字段' + checkRes.msg};
                        throw new Error();
                    }
                })
            } catch (e) {
            }
        }
        return checkReuslt;
    }
}
export default Validator